package promote.brozen.spring.lifecycle;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.stereotype.Component;

/**
 * @author Brozen
 * @date 2020/8/30 9:56 PM
 * @email brozen@qq.com
 */
@Slf4j
@Component
public class MyBeanPostProcessor implements InstantiationAwareBeanPostProcessor {

    private String logBeanName;

    public MyBeanPostProcessor(String logBeanName) {
        this.logBeanName = logBeanName;
    }

    // BeanPostProcessor
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (this.logBeanName.equalsIgnoreCase(beanName)) {
            log.info("{} - {} postProcessAfterInitialization", beanName, bean.toString());
        }
        // 在这个方法执行的时候可以做动态代理
        return bean;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (this.logBeanName.equalsIgnoreCase(beanName)) {
            log.info("{} - {} postProcessBeforeInitialization", beanName, bean.toString());
            // 但如果这里return了一个新的对象，后面的aware方法、属性注入还是会执行的
            return new JustABean("Tag when setted in Initialization");
        }
        return null;
    }

    // InstantiationAwareBeanPostProcessor
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        if (this.logBeanName.equalsIgnoreCase(beanName)) {
            log.info("{} - {} postProcessBeforeInstantiation", beanName, beanClass.toString());
            // 如果这里return了一个对象，则后续的实例化、调用Aware方法、属性依赖注入等都不会再执行
            // return new JustABean("Tag when setted in Instantiation");
        }
        return null;
    }

    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        if (this.logBeanName.equalsIgnoreCase(beanName)) {
            log.info("{} - {} postProcessAfterInstantiation", beanName, bean.toString());
        }
        return true;
    }

    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        if (this.logBeanName.equalsIgnoreCase(beanName)) {
            log.info("{} - {} postProcessProperties {}", beanName, bean.toString(), pvs.toString());
        }
        return null;
    }

}
